//
//  FTPHandler.swift
//  PLDownload
//
//  Created by bin hu on 2025/7/7.
//

import Foundation
import CFNetwork
/* FTP协议处理 */
//class FTPHandler: ProtocolHandler {
//    private var task: DownloadTask
//    private var inputStream: InputStream?
//    private var outputStream: OutputStream?
//    private var buffer = Data()
//    private var totalBytesWritten: Int64 = 0
//    
//    init(task: DownloadTask) {
//        self.task = task
//    }
//    
//    func startDownload(manager: DownloadManager) {
//        guard let url = task.url else { return }
//        
//        // 创建带断点续传参数的FTP请求
//        var requestURL = url.absoluteString
//        if let resumeData = loadResumeData() {
//            requestURL += "?restart=\(resumeData.bytesDownloaded)"
//        }
//        
//        CFURLCreateWithString(nil, requestURL as CFString, nil).flatMap {
//            let ftpStream = CFReadStreamCreateWithFTPURL(nil, $0)
//            self.inputStream = ftpStream?.takeRetainedValue()
//            
//            // 设置认证信息
//            self.inputStream?.setProperty(url.user, forKey: .ftpUserName)
//            self.inputStream?.setProperty(url.password, forKey: .ftpPassword)
//            
//            // 配置被动模式（避免防火墙问题）
//            CFReadStreamSetProperty(ftpStream,
//                                    CFStreamPropertyKey(kCFStreamPropertyFTPUsePassiveMode),
//                                    kCFBooleanTrue)
//            
//            self.inputStream?.schedule(in: .current, forMode: .default)
//            self.inputStream?.delegate = self
//            self.inputStream?.open()
//        }
//    }
//    
//    func pauseDownload() {
//        inputStream?.close()
//        outputStream?.close()
//    }
//    
//    func resumeDownload() {
//        startDownload(manager: DownloadManager.shared)
//    }
//    
//    func cancelDownload() {
//        inputStream?.close()
//        outputStream?.close()
//        FileManager.default.removeItem(at: localFileURL())
//    }
//    
//    private func localFileURL() -> URL {
//        return FileManager.default.temporaryDirectory
//            .appendingPathComponent(task.id.uuidString)
//            .appendingPathExtension(task.fileType)
//    }
//    
//    private func loadResumeData() -> ResumeData? {
//        let path = resumeDataPath()
//        guard FileManager.default.fileExists(atPath: path),
//              let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
//            return nil
//        }
//        return try? JSONDecoder().decode(ResumeData.self, from: data)
//    }
//    
//    private func saveResumeData(bytesDownloaded: Int64) {
//        let data = ResumeData(bytesDownloaded: bytesDownloaded)
//        if let encoded = try? JSONEncoder().encode(data) {
//            try? encoded.write(to: URL(fileURLWithPath: resumeDataPath()))
//        }
//    }
//}
//
//extension FTPHandler: StreamDelegate {
//    func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
//        switch eventCode {
//            case .openCompleted:
//                // 连接建立成功
//                prepareOutputStream()
//                
//            case .hasBytesAvailable:
//                // 读取数据并写入文件
//                let bufferSize = 1024
//                let buffer = UnsafeMutablePointer8<UInt>.allocate(capacity: bufferSize)
//                defer { buffer.deallocate() }
//                
//                while inputStream?.hasBytesAvailable == true {
//                    let bytesRead = inputStream!.read(buffer, maxLength: bufferSize)
//                    if bytesRead > 0 {
//                        let bytesWritten = outputStream?.write(buffer, maxLength: bytesRead) ?? 0
//                        totalBytesWritten += Int64(bytesWritten)
//                        // 更新进度
//                        DownloadManager.shared.updateTaskProgress(
//                            id: task.id,
//                            bytesDownloaded: totalBytesWritten
//                        )
//                    }
//                }
//                
//            case .endEncountered:
//                // 下载完成
//                completeDownload()
//                
//            case .errorOccurred:
//                // 保存断点信息
//                saveResumeData(bytesDownloaded: totalBytesWritten)
//                DownloadManager.shared.updateTaskState(id: task.id, state: .paused)
//                
//            default: break
//        }
//    }
//}

class FTPHandler: NSObject {
    private var inputStream: InputStream?
    private var outputStream: OutputStream?
    private var task: DownloadTask
    private var totalBytesWritten: Int64 = 0
    private var bufferSize = 8192 // 优化缓冲区大小^1^^2^
    
    init(task: DownloadTask) {
        self.task = task
        super.init()
    }
    
    func startDownload() {
        guard let url = task.url else { return }
        
        // 创建带断点参数的FTP请求^1^^3^
        var requestURL = url.absoluteString
        if let resumeData = loadResumeData() {
            requestURL += "?restart=\(resumeData.bytesDownloaded)"
            totalBytesWritten = resumeData.bytesDownloaded
        }
        
        // 配置流对象^3^^4^
        CFURLCreateWithString(nil, requestURL as CFString, nil).flatMap {
            let ftpStream = CFReadStreamCreateWithFTPURL(nil, $0)
            self.inputStream = ftpStream?.takeRetainedValue()
            
            // 认证配置^1^^5^
            self.inputStream?.setProperty(url.user, forKey: .ftpUserName)
            self.inputStream?.setProperty(url.password, forKey: .ftpPassword)
            
            // 强制被动模式^1^^2^
            CFReadStreamSetProperty(ftpStream,
                                  CFStreamPropertyKey(kCFStreamPropertyFTPUsePassiveMode),
                                  kCFBooleanTrue)
            
            self.inputStream?.delegate = self
            self.inputStream?.schedule(in: .current, forMode: .default)
            self.inputStream?.open()
        }
    }
    
    private func prepareOutputStream() {
        let fileURL = localFileURL()
        
        // 追加模式写入^1^^6^
        if FileManager.default.fileExists(atPath: fileURL.path) {
            totalBytesWritten = Int64((try? FileManager.default.attributesOfItem(atPath: fileURL.path)[.size]) as? Int64 ?? 0)
        }
        
        outputStream = OutputStream(url: fileURL, append: true)
        outputStream?.open()
    }
    
    private func loadResumeData() -> ResumeData? {
        let path = resumeDataPath()
        guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)),
              let resumeData = try? JSONDecoder().decode(ResumeData.self, from: data),
              FileManager.default.fileExists(atPath: localFileURL().path) else {
            return nil
        }
        return resumeData
    }
    
    private func saveResumeData() {
        let data = ResumeData(bytesDownloaded: totalBytesWritten,
                            fileHash: localFileHash(),
                            timestamp: Date())
        if let encoded = try? JSONEncoder().encode(data) {
            try? encoded.write(to: URL(fileURLWithPath: resumeDataPath()))
        }
    }
}

extension FTPHandler: StreamDelegate {
    func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
        switch eventCode {
        case .openCompleted:
            prepareOutputStream()
            
        case .hasBytesAvailable:
            let buffer = UnsafeMutablePointer8<UInt>.allocate(capacity: bufferSize)
            defer { buffer.deallocate() }
            
            while inputStream?.hasBytesAvailable == true {
                let bytesRead = inputStream!.read(buffer, maxLength: bufferSize)
                if bytesRead > 0 {
                    let bytesWritten = outputStream?.write(buffer, maxLength: bytesRead) ?? 0
                    totalBytesWritten += Int64(bytesWritten)
                    // 更新进度回调^4^^7^
                    DownloadManager.shared.updateProgress(for: task.id,
                                                        bytesWritten: totalBytesWritten)
                }
            }
            
        case .endEncountered:
            completeDownload()
            
        case .errorOccurred:
            saveResumeData()
            DownloadManager.shared.updateState(for: task.id, state: .paused)
            
        default: break
        }
    }
}

struct ResumeData: Codable {
   let bytesDownloaded: Int64
   let fileHash: String?
   let timestamp: Date
   
   // 添加文件校验逻辑^1^^5^
   func isValid(for fileURL: URL) -> Bool {
       guard let storedHash = fileHash else { return true }
       return storedHash == fileURL.sha1Hash()
   }
}


